#pragma once


struct SDL_Rect;


//must be an actual array
template<class T>
int math_get_array_elements(T ary)
{
	int Result = sizeof(ary) / sizeof(ary[0]);
	return Result;
}

template<class T>
float math_get_signf(T value)
{
	float Result = value < 0.0f ? (-1.0f) : (1.0f);
	return Result;
}

template<class T>
T math_get_min(T a, T b)
{
	T Result = a < b ? a : b;
	return Result;
}

template<class T>
T math_get_max(T a, T b)
{
	T Result = a > b ? a : b;
	return Result;
}



float math_absf(float val);
struct V2i;

struct V2
{
	float x;
	float y;

	operator V2i();
	bool operator==(const V2 a);
	V2 operator - (const V2 a);
	V2 operator + (const V2 a);
	V2 operator * (float f);
	V2 operator * (const V2 a);
	V2 operator / (const V2 a);
	float distance_to_squared(V2 a);
};



//create a vector [x,y] = [value,value]
V2 v2(float value);
V2 v2(float x, float y);


bool math_between(float test, float a, float b);
bool math_rect_overlap(SDL_Rect * a, SDL_Rect * b);
bool math_rect_overlap(V2 a_min, V2 a_max, V2 b_min, V2 b_max);
//integer vector

struct V2i
{
	int x;
	int y;

	operator V2();
	bool operator==(const V2i a);
	V2i operator - (const V2i a);
	V2i operator + (const V2i a);
	V2i operator * (int f);
	V2i operator * (const V2i a);
	V2i operator / (const V2i a);
	int distance_to_squared(const V2i a);
};

struct Recti
{
	V2i min;
	V2i max;
};

 Recti recti(V2i Min, V2i Max);
 Recti recti(int minx, int miny, int maxx, int maxy);
 Recti recti_centre(int x_pos, int y_pos, int width, int height);
 Recti recti_centre(V2i pos,V2i size);

struct Rect
{
	V2 min;
	V2 max;
};

 Rect rect(V2 Min, V2 Max);
 Rect rect(float minx, float miny, float maxx, float maxy);
 Rect rect_centre(float x_pos, float y_pos, float width, float height);
 Rect rect_centre(V2 pos,V2 size);

//create a vector [x,y] = [value,value]
V2i v2i(int value);
V2i v2i(int x, int y);
//un const
V2i v2i(const V2i v);

bool math_point_in_rect(V2i p, V2i rectStart, V2i rectEnd);
bool math_point_in_rect(V2 p, V2 rectStart, V2 rectEnd);

//get this to work in vectors//
V2 math_subtract(const V2 a, const V2 b);

//returns true if capped
bool math_cap_values(V2 & value, V2 min, V2 max);

//returns true if capped
bool math_cap_values(V2i & value, V2i min, V2i max);

//returns true if asserted
bool math_values_in_range(V2 value, V2 min, V2 max);

//returns true if asserted
bool math_values_in_range(V2i value, V2i min, V2i max);

bool math_point_in_rect(V2i p, Recti r);

bool math_point_in_rect(V2 p, Rect r);

bool math_rect_overlap(Rect a, Rect b);

/*
returns 2 grid vertices. Positioned at corners (tl, br) that the rect intersects, grid is positioned at origin.
*/
static inline Recti math_rect_integer_divide(float grid_spacing, Rect r)
{
	Recti Result =
	{
		(int)(r.min.x / grid_spacing),
		(int)(r.min.y / grid_spacing),
		(int)(r.max.x / grid_spacing),
		(int)(r.max.y / grid_spacing)
	};
	return Result;
}

/*
returns 2 grid vertices. Positioned at corners (tl, br) that the rect intersects, grid is positioned at origin.
*/
static inline Rect math_rect_divide(float grid_spacing, Rect r)
{
	Rect Result =
	{
		(r.min.x / grid_spacing),
		(r.min.y / grid_spacing),
		(r.max.x / grid_spacing),
		(r.max.y / grid_spacing)
	};
	return Result;
}
